//
//  AFHTTPClient.m
//  xiaoTest
//
//  Created by Xiaoshiheng_pro on 2016/12/13.
//  Copyright © 2016年 xiao_shoubao. All rights reserved.
//


#import "AFHTTPClient.h"

#import <CommonCrypto/CommonDigest.h>

#define KeyCode @"_9GAT595XUIZHYJQZGW7608Q3C5BE98VCXPB8"

@implementation AFHTTPClient

#pragma mark - 其他---------
/* 输出http响应的状态码 */
+ (void)showResponseCode:(NSURLResponse *)response {
    
    NSHTTPURLResponse* httpResponse = (NSHTTPURLResponse*)response;
    NSInteger responseStatusCode = [httpResponse statusCode];
    NSLog(@"%zi", responseStatusCode);
}
//控件显示百分比,这个随意  写这里 怕忘了
+ (void)updateProgress:(NSProgress*)progress{
    /*
     @property int64_t totalUnitCount;  需要下载文件的总大小
     @property int64_t completedUnitCount; 当前已经下载的大小
     */
    dispatch_async(dispatch_get_main_queue(), ^(void){
        //Run UI Updates
        CGFloat progressf = (CGFloat)progress.completedUnitCount/(CGFloat)(progress.totalUnitCount+1);
        progressf = progressf*100;
        NSString* showStr = [NSString stringWithFormat:@"%0.f%c",progressf,'%'];
        NSLog(@"%@",showStr);
    });
    
    NSLog(@"%lld  %lld",progress.totalUnitCount,progress.completedUnitCount);
}

#pragma mark ----------------加密组合接口------------------------
+( NSDictionary *)JMWithStringUrl:(NSString *)URL   parameters:(NSDictionary *)parameters{
    
    NSMutableDictionary * JMdic = [NSMutableDictionary dictionaryWithCapacity:0];
    
    
    
    NSString *token =  [self MD5EncryptionWithString:kStringFormat(@"%@%@",URL,KeyCode)];
    
    [JMdic setValue:token forKey:@"token"];
    
    if (ISLOGIN) {
        
//        UserModel *model = [UserModel UserModelInit];
//        [JMdic setValue:model.ID forKey:@"uid"];
//        [JMdic setValue:model.logsign forKey:@"logsign"];
    }

    [JMdic addEntriesFromDictionary:parameters];
    
    return JMdic;
    
}

+ (NSString *)MD5EncryptionWithString:(NSString *)string{
    
    //1.首先将字符串转换成UTF-8编码, 因为MD5加密是基于C语言的,所以要先把字符串转化成C语言的字符串
    const char *fooData = [string UTF8String];
    
    //2.然后创建一个字符串数组,接收MD5的值
    unsigned char result[CC_MD5_DIGEST_LENGTH];
    
    //3.计算MD5的值, 这是官方封装好的加密方法:把我们输入的字符串转换成16进制的32位数,然后存储到result中
    CC_MD5(fooData, (CC_LONG)strlen(fooData), result);
    /**
     第一个参数:要加密的字符串
     第二个参数: 获取要加密字符串的长度
     第三个参数: 接收结果的数组
     */
    
    //4.创建一个字符串保存加密结果
    NSMutableString *saveResult = [NSMutableString string];
    
    //5.从result 数组中获取加密结果并放到 saveResult中
    for (int i = 0; i < CC_MD5_DIGEST_LENGTH; i++) {
        [saveResult appendFormat:@"%02x", result[i]];
    }
    /*
     x表示十六进制，%02X  意思是不足两位将用0补齐，如果多余两位则不影响
     NSLog("%02X", 0x888);  //888
     NSLog("%02X", 0x4); //04
     */
    return saveResult;
}

#pragma mark - 设置AFHTTPSessionManager相关属性
+ (AFHTTPSessionManager*)httpSessionManagerWithBaseUrl:(NSString*)baseUrl Headers:(NSDictionary *)headers{
    
    //打开状态栏的等待菊花
    [AFNetworkActivityIndicatorManager sharedManager].enabled = YES;
    
    NSURLSessionConfiguration *sessionConfiguration = [NSURLSessionConfiguration defaultSessionConfiguration];
    //设置请求超时时间
    sessionConfiguration.timeoutIntervalForRequest =HTTPTimeoutInterval;
    //设置请求headers
    if (headers) {
        sessionConfiguration.HTTPAdditionalHeaders = headers;
    }
    
    AFHTTPSessionManager *manager = [[AFHTTPSessionManager alloc] initWithBaseURL:[NSURL URLWithString:baseUrl] sessionConfiguration:sessionConfiguration];
    
    // 设置返回格式
    manager.responseSerializer = [AFJSONResponseSerializer serializer];
    manager.responseSerializer.acceptableContentTypes = [NSSet setWithObjects:@"application/json", @"text/json", @"text/javascript", @"text/html", @"charset=UTF-8", nil];

    return manager;
    
    
}
#pragma mark -
#pragma mark - 请求成功,处理响应数据
+ (void)handleResponseObject:(id)responseObject successBlock:(HttpRequestSuccess)success{
    
    ///可以在此 处理其他事
    
    //NSDictionary *dict = responseObject;
    //BOOL isAccess = [[dict valueForKey:@"IsAccess"]boolValue];
    //NSDictionary *datalist = [dict valueForKey:@"Result"];
    //NSString *msg_server = [dict valueForKey:@"Pmg"];
 
    
    DLog(@"responseObject = %@",responseObject);
    success ? success(responseObject) : nil;
    
        
}
#pragma mark -
#pragma mark - 请求失败
+ (void)handleRequestFailure:(NSError*)error failureBlock:(HttpRequestFailed)failure;{
    
    NSString *string = nil;
    switch (error.code) {
        case -1001:
            string =@"请求超时";
            break;
        case -1002:
            string = @"连接地址错误";
            break;
        case -1003:
            string =@"未能找到服务器。";
            break;
        case -1004:
            string =@"连接不上服务器";
            break;
        case -1005:
            string =@"网络连接已中断";
            break;
        case -1009:
            string =@"已断开与互联网的连接。";
            break;
        case -1011:
            
            string = error.localizedDescription ;
            
            break;
        case -1016:
            string =@"服务内部错误";
            break;
        case 3840:
            string =@"请求接口不完整";
            break;
        default:
            string = [NSString stringWithFormat:@"错误代码%zi",error.code];
            break;
    }
    
    DLog(@"错误信息 = %@ \nerror = %@",string,error);
    failure ? failure([self requestErrorWithDescription:string errorCode:error.code]) : nil;
    
}
#pragma mark -
#pragma mark - 生成错误信息
+ (NSError*)requestErrorWithDescription:(NSString*)description errorCode:(NSInteger)errorCode{
    
    NSDictionary *userInfo =  [NSDictionary dictionaryWithObject:description forKey:NSLocalizedDescriptionKey];
    
    NSError *error = [NSError errorWithDomain:@"Domain" code:errorCode userInfo:userInfo];
    
    return error;
}
#pragma mark - POST请求自动缓存
+ (NSURLSessionTask *)requestPOSTWithServerPath:(NSString *)serverPath
                                        Headers:(NSDictionary *)headers
                                   relativePath:(NSString*)relativePath
                                     parameters:(NSDictionary *)parameters
                             responseCacheBlock:(HttpRequestCache)responseCache
                                   successBlock:(HttpRequestSuccess)success
                                   failureBlock:(HttpRequestFailed)failure;

{
    //读取缓存
    responseCache ? responseCache([AFHTTPCache getHttpCacheForKey:relativePath]) : nil;

    AFHTTPSessionManager *manager = [self httpSessionManagerWithBaseUrl:serverPath Headers:headers];

    NSURLSessionDataTask *dataTask = [manager POST:relativePath parameters:parameters progress:^(NSProgress *uploadProgress){
        
    }success:^(NSURLSessionDataTask *task, id responseObject)
    {
                                          
        [self handleResponseObject:responseObject successBlock:success];
        //对数据进行异步缓存
        responseCache ? [AFHTTPCache saveHttpCache:responseObject forKey:relativePath] : nil;
        
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
        
        [self handleRequestFailure:error failureBlock:failure];
                                          
                                          
    }];
    
    return dataTask;
    
}
#pragma mark - GET请求自动缓存
+ (__kindof NSURLSessionTask *)requestGETWithServerPath:(NSString *)serverPath
                                                Headers:(NSDictionary *)headers
                                           relativePath:(NSString*)relativePath
                                             parameters:(NSDictionary *)parameters
                                     responseCacheBlock:(HttpRequestCache)responseCache
                                           successBlock:(HttpRequestSuccess)success
                                           failureBlock:(HttpRequestFailed)failure
{
    
    //读取缓存
    responseCache ? responseCache([AFHTTPCache getHttpCacheForKey:relativePath]) : nil;
    
    AFHTTPSessionManager *manager = [self httpSessionManagerWithBaseUrl:serverPath Headers:headers];
    
    NSURLSessionDataTask *dataTask = [manager GET:relativePath parameters:parameters progress:^(NSProgress *uploadProgress){
        
    }success:^(NSURLSessionDataTask *task, id responseObject)
    {
                                          
        [self handleResponseObject:responseObject successBlock:success];
        //对数据进行异步缓存
        responseCache ? [AFHTTPCache saveHttpCache:responseObject forKey:relativePath] : nil;
        
    } failure:^(NSURLSessionDataTask *task, NSError *error) {
                                          
        [self handleRequestFailure:error failureBlock:failure];
                                          
                                          
    }];
    
    return dataTask;
    
}

#pragma ++++++++++++++++++++++++++++++下载功能+++++++++++++++++++++++++
#pragma mark - 下载文件
+ (__kindof NSURLSessionTask *)downloadWithdownloadPath:(NSString *)downloadPath
                                                fileDir:(NSString *)fileDir
                                          progressBlock:(HttpProgress)progress
                                           successBlock:(void(^)(NSString *filePath))success
                                           failureBlock:(HttpRequestFailed)failure
{
    
    AFURLSessionManager *manager = [[AFURLSessionManager alloc] initWithSessionConfiguration:[NSURLSessionConfiguration defaultSessionConfiguration]];
    NSString *urlString = [downloadPath stringByAddingPercentEscapesUsingEncoding:NSUTF8StringEncoding];
    NSURLRequest *request = [NSURLRequest requestWithURL:[NSURL URLWithString:urlString]];

    NSURLSessionDownloadTask *downloadTask = [manager downloadTaskWithRequest:request progress:^(NSProgress * _Nonnull downloadProgress) {
        //下载进度
        
#if DEBUG
        progress ? progress(downloadProgress) : nil;
        progress ? [self updateProgress:downloadProgress] : nil;
#else
        progress ? progress(downloadProgress) : nil;
#endif

        
        
    } destination:^NSURL * _Nonnull(NSURL * _Nonnull targetPath, NSURLResponse * _Nonnull response) {
        
        //拼接缓存目录
        NSString *downloadDir = [[NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES) lastObject] stringByAppendingPathComponent:fileDir ? fileDir : @"Download"];
        //打开文件管理器
        NSFileManager *fileManager = [NSFileManager defaultManager];
        
        //创建Download目录
        [fileManager createDirectoryAtPath:downloadDir withIntermediateDirectories:YES attributes:nil error:nil];
        
        //拼接文件路径
        NSString *filePath = [downloadDir stringByAppendingPathComponent:response.suggestedFilename];
        
        NSLog(@"downloadDir = %@",downloadDir);
        
        //返回文件位置的URL路径
        return [NSURL fileURLWithPath:filePath];
        
    } completionHandler:^(NSURLResponse * _Nonnull response, NSURL * _Nullable filePath, NSError * _Nullable error) {
        
        success ? success(filePath.absoluteString /** NSURL->NSString*/) : nil;
        failure && error ? failure(error) : nil;
        
    }];
    
    //开始下载
    [downloadTask resume];
    
    return downloadTask;
    
}
#pragma ++++++++++++++++++++++++++++++上传功能+++++++++++++++++++++++++
+ (__kindof NSURLSessionTask *)uploadWithServerPath:(NSString *)serverPath
                                            Headers:(NSDictionary *)headers
                                       relativePath:(NSString*)relativePath
                                         parameters:(NSDictionary *)parameters
                                             photos:(NSArray <UIImage *>*)photos
                                         photoNames:(NSArray*)photoNames
                                           progress:(HttpProgress)progress
                                            success:(HttpRequestSuccess)success
                                            failure:(HttpRequestFailed)failure
{

    AFHTTPSessionManager *manager = [self httpSessionManagerWithBaseUrl:serverPath Headers:headers];
    return [manager POST:relativePath parameters:parameters constructingBodyWithBlock:^(id<AFMultipartFormData>  _Nonnull formData) {
        
        //压缩-添加-上传图片
        for (NSInteger i = 0; i < photos.count; i++) {
            
            [formData appendPartWithFileData:UIImageJPEGRepresentation(photos[i], 0.3) name:photoNames[i] fileName:[NSString stringWithFormat:@"iosphoto%f%i.jpg", [[NSDate date] timeIntervalSince1970], (int)i] mimeType:@"image/jpeg"];
            
        }
        
    } progress:^(NSProgress * _Nonnull uploadProgress) {
        //上传进度
        progress ? progress(uploadProgress) : nil;
        
    } success:^(NSURLSessionDataTask * _Nonnull task, id  _Nullable responseObject) {
        
        
        [self handleResponseObject:responseObject successBlock:success];
        
        
    } failure:^(NSURLSessionDataTask * _Nullable task, NSError * _Nonnull error) {
        
        [self handleRequestFailure:error failureBlock:failure];
        
    }];



}

@end
